<?php
/*
 * 管理员后台生成静态文件（磁盘缓存）：用户访问时不用读取数据库，列表页和详情页都是读取文件，提高了访问速度
 * 1、添加或更新一条记录时，用详情页公共模板生成对应的静态文件；
 * 2、添加或更新了一些记录后，一键功能，用列表页模板生成时时静态文件
 * */
class Cache_file
{
       private $cache_project_dir;
    private $cache_project_detail_filename_pre;//如：family_
    private $cache_project_list_filename;//不带后缀的文件名称,eg.family_list
    private $cache_project_file_suffix;
    private $cache_project_url;         // 缓存模块的url路径
    public $error;
    private $rewrite_list_session_key;       //String，保存在session的键名rewrite_list_session_key，当写入操作时用到

    /**
     * @param $cache_project ：要缓存的模块名称:eg.family，以此命名文件夹
     */
    public function __construct($cache_project)
    {
        $this->cache_project_dir = CACHE_STATIC_DIR .DS. $cache_project;
        $this->cache_project_detail_filename_pre = $cache_project . '_detail_';
        $this->cache_project_list_filename = $cache_project . '_list';

        $this->cache_project_url = CACHE_URL . DS . 'cache_static' . DS . $cache_project;
        $this->cache_project_file_suffix = $GLOBALS['config']['cache_file']['cache_project_file_suffix'];

        $this->rewrite_list_session_key = $GLOBALS['config']['cache_file']['rewrite_list_session_key'];
    }
    public function checkConfigCacheFile($tablename,$file_detail_url_field){
        $fields_str = DB::queryAllFields($tablename);
        is_string($fields_str) or die('没有查询到字段');
        $fileds_array = explode(',',$fields_str);
        if(in_array($file_detail_url_field,$fileds_array)){
            return true;
        }else{
            return false;
        }

    }
    /**
     * @param String $tablename
     * @param $insert_array
     *   @param String $tpl_detail_name：详情页模板名称
     *  @param String $file_detail_url_field：数据库中保存对象的静态文件url的字段名
     * @return bool：返回true,则表示插入数据库和生成详情页静态文件成功
     */
    public function addRecordAndFile($tablename, $insert_array,$tpl_detail_name,$file_detail_url_field)
    {   if(!$this->checkConfigCacheFile($tablename,$file_detail_url_field)){
            $this->error ='参数：“$file_detail_url_field”有误，要同数据库一致';
            return false;
        }
        $increment_id = DB::Insert($tablename, $insert_array);
        if (!$increment_id) {
            $this->error = "插入数据库出错";
            return false;
        }
        $tpl_detail_path = TPLS_DIR . DS . $tpl_detail_name;
        $rs_tpl = fopen($tpl_detail_path, 'r');
        if(!is_dir($this->cache_project_dir)){
            mkdir($this->cache_project_dir,0777,true);
        }
        $cache_project_detail_filepath = $this->cache_project_dir . DS . $this->cache_project_detail_filename_pre . $increment_id . '.' . $this->cache_project_file_suffix;
        $rs_detail = fopen($cache_project_detail_filepath, 'w');
        $tpl_str = '';
        while (!feof($rs_tpl)) {
            $tpl_str .= fgets($rs_tpl);
        }
        foreach ($insert_array as $k => $v) {
            $tpl_str = str_replace('{' . $k . '}', $v, $tpl_str);
        }
        if (fwrite($rs_detail, $tpl_str)) {
            fclose($rs_tpl);
            fclose($rs_detail);
            $_SESSION[$this->rewrite_list_session_key] = true;
            $file_url = $this->cache_project_url.DS.$this->cache_project_detail_filename_pre . $increment_id . '.' . $this->cache_project_file_suffix;
            $update_array=array($file_detail_url_field=>$file_url);
            if(DB::Update($tablename,$update_array,"news_id='$increment_id'")){
                return true;
            }else{
                $this->error = "更新详情页的url出错";
                return false;
            }

        } else {
            $this->error = "添加文件内容出错";
            return false;
        }

    }

    /**
     * @param $tablename ：要编辑的表名
     * @param $update_array：编辑数组，表明编辑对象哪些字段的值
     * @param $where：条件，表明编辑的对象
     * @param $id：编辑对象的id编号
     * @param $tpl_detail_name：详情页模板名称
     * @return bool：返回true则更新对象的数据库和文件成功
     */
    public function updateRecordAndFile($tablename, $update_array, $where, $id,$tpl_detail_name)
    {

        if (!DB::Update($tablename, $update_array, $where)) {
            $this->error = "没做更改或数据库编辑失败";
            return false;
        }
        $tpl_detail_path = TPLS_DIR . DS . $tpl_detail_name;
        $tpl_str = file_get_contents($tpl_detail_path);
        $cache_project_detail_filepath = $this->cache_project_dir . DS . $this->cache_project_detail_filename_pre . $id . '.' . $this->cache_project_file_suffix;
        foreach($update_array as $k=>$v){
            $tpl_str = str_replace('{' . $k . '}', $v, $tpl_str);
        }
       if( file_put_contents($cache_project_detail_filepath,$tpl_str)){
           $_SESSION[$this->rewrite_list_session_key] = true;
            return true;
       }else{
           $this->error = "更新文件内容出错";
           return false;
       }

    }
    public function delRecordAndFile($table,$where,$id){
        if(!DB::Delete($table,$where)){
            $this->error = "删除数据库一条记录出错";
            return false;
        }
        $cache_project_detail_filepath = $this->cache_project_dir . DS . $this->cache_project_detail_filename_pre . $id . '.' . $this->cache_project_file_suffix;
        if(!is_file($cache_project_detail_filepath)){
            $_SESSION[$this->rewrite_list_session_key] = true;
            return true;
        }

        if(unlink($cache_project_detail_filepath)){
            $_SESSION[$this->rewrite_list_session_key] = true;
            return true;
        }else{
            $this->error = "删除一个文件失败";
            return false;
        }

    }

    /**
     * @param $table
     * @param $where
     * @param $id_array：多条记录的id组成的数组
     * @return bool：返回true时，同‘多个对象’的数据库记录和文件同时删除
     */
    public function delMoreRecordsAndFiles($table,$where,$id_array){
        if(!DB::Delete($table,$where)){
            $this->error = "删除数据库多条记录出错";
            return false;
        }
        foreach($id_array as $id){
            $cache_project_detail_filepath = $this->cache_project_dir . DS . $this->cache_project_detail_filename_pre . $id . '.' . $this->cache_project_file_suffix;
            if(!is_file($cache_project_detail_filepath)){
                continue;
            }
            if(!unlink($cache_project_detail_filepath)){
                $this->error = "删除多个文件出错";
                return false;
            }
        }
        $_SESSION[$this->rewrite_list_session_key] = true;
        return true;
    }

    /**
     * 生成列表页静态文件：条件是文件不存在 或 对数据库进行了写入（cud）操作
     * @param $sql:查询列表的sql
     * @param $tpl_list_name：列表页模板名称：xxx.php
     */
    public function addCacheList($sql,$tpl_list_name){
        $cache_list_path = $this->cache_project_dir . DS . $this->cache_project_list_filename . '.' . $this->cache_project_file_suffix;
        if(is_file($cache_list_path) && !isset($_SESSION[$this->rewrite_list_session_key])){
            echo "<script>alert('已经生成，不用重复操作');</script>";
            exit;
        }

        $list = DB::queryAll($sql);
        include_once TPLS_DIR.DS.$tpl_list_name;
        $flist_str = ob_get_contents();
        ob_clean();
        file_put_contents($cache_list_path,$flist_str);
        echo "<script>alert('成功生成最新静态文件');</script>";
        if(isset($_SESSION[$this->rewrite_list_session_key])){
            unset($_SESSION[$this->rewrite_list_session_key]);
        }
    }

}

